<template>
    <div>
        <el-input
                placeholder="输入关键字进行过滤"
                clearable
                size="mini"

                @dblclick.native="dblclick"
                v-model="filterText">
        </el-input>
        <el-tree
                ref="tree"
                :data="computedTreeData"
                :props="computedProps"
                v-bind="computedProp"
                v-loading="localLoading"
                @node-click="(data,node,com)=>{$emit('nodeClick',data,node,com)}"
                @check-change="checkChange"
        ></el-tree>
    </div>

</template>

<script>

    export default {
        name: 'StElTree',
        props: {
            value: Array,
            // 被包装组件的原始属性
            originProp: {
                type: Object,
                default: function () {
                    return {}
                }
            },
            originProps: {
                type: Object,
                default: function () {
                    return {}
                }
            },
            // 缓存key，仅url加载有效
            cacheKey: String,
            // 自定义数据
            datas: {
                type: [Array, String],
                default: function () {
                    return []
                }
            },
        },
        computed: {
            computedTreeData(){
                return this.$stArrayTools.listToTree(this.localData,null)
            },
            computedProps() {
                let defaultProps = {
                    label: 'name', // 显示的值属性
                    children: 'children', // 子节点属性
                    isLeaf: 'leaf', // 标识叶子节点
                    disabled: 'disabled', // 指定节点选择框是否禁用为节点对象的某个属性值
                }

                let r = this.$stObjectTools.extendDeep(defaultProps, this.originProps)
                return r
            },
            computedProp() {
                let defaultProp = {
                    lazy: false, // 是否懒加载子节点
                    load: this.lazyLoad, // 加载子树数据的方法
                    nodeKey: 'id',
                    filterNodeMethod: this.filterNode,
                    expandOnClickNode: false,
                    defaultCheckedKeys: this.value
                }

                let r = this.$stObjectTools.extendDeep(defaultProp, this.originProp)
                return r
            }
        },
        data() {
            return {
                localData: [],
                localLazyLoadData: [],
                localLoading: false,
                filterText: ''
            }
        },
        mounted() {
            this.initData(this.datas)

        },
        methods: {

            // 根据url加载数据
            initDataByUrl(url) {
                if(this.cacheKey){
                    let data = this.$stStorageTools.get(this.cacheKey)
                    if(data){
                        this.localData = data
                        return
                    }
                }
                this.localLoading = true
                this.axios.get(url).then(res => {
                    this.localData = res.data
                    if(this.cacheKey){
                        this.$stStorageTools.set(this.cacheKey,res.data)
                    }
                }).catch(error => {
                    this.localData = []
                    if (error.response) {
                        if (error.response.status == 401) {
                            return
                        }
                        if (error.response.data && error.response.data.errorMsg) {
                            if (error.response.status != 404) {
                                this.$message.error(error.response.data.errorMsg)
                            }
                        }

                    } else {
                        this.$message.error('网络错误或服务不可用')
                    }
                }).finally(()=>{
                    this.localLoading = false
                })
            },
            // 加载
            initData(data) {
                if (!data) {
                    return
                }
                if (this.$stArrayTools.isArray(data)) {
                    this.localData = data
                } else if (this.$stStringTools.isString(data)) {
                    this.initDataByUrl(data)
                } else if (this.$stFunctionTools.isFunction(data)) {
                    this.initData(data())
                }
            },
            lazyLoad(node, resolve) {
                this.$emit('lazyLoadingBegin', node.data)
                let params = {parentId: this.$stObjectTools.getValue(node.data, this.computedProps.value)}
                this.axios.get(this.datas, {params: params})
                    .then((response) => {
                        let content = response.data
                        this.localLazyLoadData = this.localLazyLoadData.concat(content)
                        resolve(content)
                        this.$emit('lazyLoadingEnd', node.data, content)
                    })
                    .catch((error) => {
                        resolve([])
                        this.$emit('lazyLoadingEnd', node.data, [])
                        if (error.response) {
                            if (error.response.status == 401) {
                                return
                            }
                            if (error.response.data && error.response.data.errorMsg) {
                                if (error.response.status != 404) {
                                    this.$message.error(error.response.data.errorMsg)
                                }
                            }

                        } else {

                            this.$message.error('网络错误或服务不可用')
                        }
                    }).finally(() => {

                })
            },
            filterNode(value, data) {
                if (!value) return true;
                return data[this.computedProps.label].indexOf(value) !== -1;
            },
            checkChange(data,isCurrentSelected,isChildrenSelected) {
                this.$emit('checkChange',data,isCurrentSelected,isChildrenSelected)
                this.$emit('input',this.$refs.tree.getCheckedKeys())
            },
          dblclick(){
            this.initData(this.datas)
          }
        },
        watch: {
            datas(val) {
                this.initData(val)
            },
            filterText(val) {
                this.$refs.tree.filter(val);
            },
            value(val) {
                this.$refs.tree.setCheckedKeys(val || [])
            }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
